<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>RVM : The MMTk Test Harness</title>
	    <link rel="stylesheet" href="styles/site.css" type="text/css" />
        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">	    
    </head>

    <body>
	    <table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#ffffff">
		    <tr>
			    <td valign="top" class="pagebody">
				    <div class="pageheader">
					    <span class="pagetitle">
                            RVM : The MMTk Test Harness
                                                    </span>
				    </div>
				    <div class="pagesubheading">
					    This page last changed on Mar 09, 2009 by <font color="#0050B2">rgarner</font>.
				    </div>

				    <h1><a name="TheMMTkTestHarness-Overview"></a>Overview</h1>

<p>The MMTk harness is a debugging tool. It allows you to run MMTk with a simple client - a simple Java-like scripting language - which can explicitly allocate objects, create and delete references, etc. This allows MMTk to be run and debugged stand-alone, without the entire VM, greatly simplifying initial debugging and reducing the edit-debug turnaround time. This is all accessible through the command line or an IDE such as eclipse.</p>

<h1><a name="TheMMTkTestHarness-Runningthetestharness"></a>Running the test harness</h1>

<p>The harness can be run standalone or via Eclipse (or other IDE).</p>

<h2><a name="TheMMTkTestHarness-Standalone"></a>Standalone</h2>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">ant mmtk-harness
java -jar target/mmtk/mmtk-harness.jar &lt;script-file&gt; [options...]</pre>
</div></div>
<p>There is a collection of sample scripts in the MMTk/harness/test-scripts directory.&nbsp; There is a simple wrapper script that runs all the available scripts against all the collectors,</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">bin/test-mmtk [options...]</pre>
</div></div>
<p>&nbsp;This script prints a PASS/FAIL line as it goes, and puts detailed output in results/mmtk.</p>

<h2><a name="TheMMTkTestHarness-InEclipse"></a>In Eclipse</h2>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">ant mmtk-harness-eclipse-project</pre>
</div></div>
<p>Define a new run configuration with main class org.mmtk.harness.Main.&nbsp; The harness makes extensive use of the java 'assert' keyword, so you should run the harness with '-ea' in the VM options.</p>

<p>You can configure eclipse to display vmmagic values (Address/ObjectReference/etc) using their toString method through the Eclipse &#45;&gt; Preferences... &#45;&gt; Java &#45;&gt; Debug &#45;&gt; Detail Formatters menu. The simplest option is to check the box to use toString 'As the label for all variables'.</p>

<h2><a name="TheMMTkTestHarness-Testharnessoptions"></a>Test harness options</h2>

<p>Options are passed to the test harness as 'keyword=value' pairs.&nbsp; The standard MMTk options that are available through JikesRVM are accepted (leave off the "-X:gc:"), as well as the following harness-specific options:</p>
<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Option <br clear="all" /> </th>
<th class='confluenceTh'> Meaning </th>
</tr>
<tr>
<td class='confluenceTd'> plan </td>
<td class='confluenceTd'> The MMTk plan class.&nbsp; Defaults to org.mmtk.plan.marksweep.MS <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> collectors </td>
<td class='confluenceTd'> The number of concurrent collector threads (default: 1) <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> initHeap </td>
<td class='confluenceTd'> Initial heap size.&nbsp; It is also a good idea to use 'variableSizeHeap=false', since the heap growth manager uses elapsed time to make its decisions, and time is seriously dilated by the MMTk Harness. <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> maxHeap </td>
<td class='confluenceTd'> Maximum heap size (default: 64 pages) <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> trace </td>
<td class='confluenceTd'> Debugging messages from the MMTk Harness.&nbsp; Trace options include
<ul>
	<li>CALL - trace procedure calls</li>
	<li>ALLOC - trace object allocation</li>
	<li>OBJECT - trace object mutation events<br clear="all" />
 See the class org.mmtk.harness.lang.Trace for more details and trace options. <br clear="all" /> </li>
</ul>
</td>
</tr>
<tr>
<td class='confluenceTd'> gcEvery </td>
<td class='confluenceTd'> Force frequent GCs.&nbsp; Options are
<ul>
	<li>ALLOC - GC after every object allocation&nbsp;</li>
	<li>SAFEPOINT - GC at every GC safepoint</li>
</ul>
</td>
</tr>
<tr>
<td class='confluenceTd'> scheduler </td>
<td class='confluenceTd'> Optionally use the deterministic scheduler.&nbsp; Options are
<ul>
	<li>JAVA (default) - Threads in the script are Java threads, scheduled by the host JVM</li>
	<li>DETERMINISTIC - Threads are scheduled deterministically, with yield points at every memory access.</li>
</ul>
</td>
</tr>
<tr>
<td class='confluenceTd'> schedulerPolicy </td>
<td class='confluenceTd'> Select from several scheduling policies,
<ul>
	<li>FIXED - Threads yield every 'nth' yield point</li>
	<li>RANDOM - Threads yield according to a pseudo-random policy</li>
	<li>NEVER - Threads only yield at mandatory yieldpoints</li>
</ul>
</td>
</tr>
<tr>
<td class='confluenceTd'> yieldInterval </td>
<td class='confluenceTd'> For the FIXED scheduling policy, the yield frequency. <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> randomPolicyLength <br clear="all" />
randomPolicySeed <br clear="all" />
randomPolicyMin <br clear="all" />
randomPolicyMax </td>
<td class='confluenceTd'> Parameters for the RANDOM scheduler policy.&nbsp; Whenever a thread is created, the scheduler fixes a yield pattern of 'length' integers between 'min' and 'max'.&nbsp; These numbers are used as yield intervals in a circular manner. <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> policyStats </td>
<td class='confluenceTd'> Dump statistics for the deterministic scheduler's yield policy. <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> bits=32&#124;64 </td>
<td class='confluenceTd'> Select between 32 and 64-bit memory models. <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> dumpPcode </td>
<td class='confluenceTd'> Dump the pseudo-code generated by the harness interpreter <br clear="all" /> </td>
</tr>
<tr>
<td class='confluenceTd'> timeout </td>
<td class='confluenceTd'> Abort collection if a GC takes longer than this value (in seconds) <br clear="all" /> </td>
</tr>
</tbody></table>
<p><br clear="all" /></p>

<h1><a name="TheMMTkTestHarness-Scriptinglanguage"></a>Scripting language</h1>


<h1><a name="TheMMTkTestHarness-"></a></h1>


<h2><a name="TheMMTkTestHarness-Basics"></a>Basics</h2>

<p>The language has three types: integer, object and user-defined. The object type behaves essentially like a double array of pointers and integers (odd, I know, but the scripting language is basically concerned with filling up the heap with objects of a certain size and reachability).&nbsp; User-defined types are like Java objects without methods, 'C' structs, Pascal record types etc.</p>

<p>Objects and user-defined types are allocated with the 'alloc' statement: alloc(p,n,align) allocates an object with 'p' pointers, 'n' integers and the given alignment; alloc(type) allocates an object of the given type.&nbsp; Variables are declared 'c' style, and are optionally initialized at declaration.</p>

<p>&nbsp;User-defined types are declared as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">type list {
  <span class="code-object">int</span> value;
  list next;
}</pre>
</div></div>
<p>and fields are accessed using java-style "dot" notation, eg</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">  list l = alloc(list);
  l.value = 0;
  l.next = <span class="code-keyword">null</span>;</pre>
</div></div>
<p>At this stage, fields can only be dereferenced to one level, eg 'l.next.next' is not valid syntax - you need to introduce a temporary variable to achieve this.</p>

<p>Object fields are referenced using syntax like "tmp.int[5]" or "tmp.object[i*3]",<br/>
ie like a struct of arrays of the appropriate types.</p>

<h2><a name="TheMMTkTestHarness-Syntax"></a>Syntax</h2>

<p><br clear="all" /></p>
<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
<pre>script ::= (method|type)...

method ::= ident "(" { type ident { "," type ident}...  ")"
           ( "{" statement... "}"
           | "intrinsic" "class" name "method" name "signature" "(" java-class {, java class} ")"

type ::= "type" ident "{" field... "}"
field ::= type ident ";"

statement ::=
	  "if" "(" expr ")" block { "elif" "(" expr ")" block } [ "else" block ]
	| "while "(" expr ")" block
	| [ [ type ] ident "=" ] "alloc" "(" expr "," expr [ "," expr ] ")" ";"
	| [ ident "=" ] "hash" "(" expr ")" ";"
        | "gc" "(" ")"
        | "spawn" "(" ident [ "," expr ]... ")" ";"
	| type ident [ "=" expr ] ";"
	| lvalue "=" expr ";"

lvalue ::= ident "=" expr ";"
	| ident "." type "[" expr "]"

type ::= "int" | "object" | ident

expr ::= expr binop expr
		| unop expr
		| "(" expr ")"
		| ident
		| ident "." type "[" expr "]"
		| ident "." ident
		| int-const
		| intrinsic

intrinsic ::= "alloc" ( "(" expr "," expr ["," expr] ")
                      | type
                      )
            | "(" expr ")"
            | "gc " "(" ")"

binop ::= "+" | "-" | "*" | "/" | "%" | "&amp;&amp;" | "||" | "==" | "!="

unop ::= "!" | "-"
</pre>
</div></div>

<h1><a name="TheMMTkTestHarness-MMTkUnitTests"></a>MMTk Unit Tests</h1>

<p>There is a small set of unit tests available for MMTk, using the harness as scaffolding.&nbsp; These tests can be run in the standard test infrastructure using the 'mmtk-unit-tests' test set, or the shell script 'bin/unit-test-mmtk'.&nbsp; Possibly more usefully, they can be run from Eclipse.</p>

<p>To run the unit tests in Eclipse, build the mmtk harness project (see above), and add the directory testing/tests/mmtk/src to your build path (navigate to the directory in the package explorer pane in eclipse, right-click&gt;build-path&gt;Use as Source Folder).&nbsp; Either open one of the test classes, or highlight it in the package explorer and press the 'run' button.
<br clear="all" /></p>

				    
                    			    </td>
		    </tr>
	    </table>
	    <table border="0" cellpadding="0" cellspacing="0" width="100%">
			<tr>
				<td height="12" background="http://docs.codehaus.org/images/border/border_bottom.gif"><img src="images/border/spacer.gif" width="1" height="1" border="0"/></td>
			</tr>
		    <tr>
			    <td align="center"><font color="grey">Document generated by Confluence on Jun 10, 2009 09:12</font></td>
		    </tr>
	    </table>
    </body>
</html>